package com.molichuxing.gateway.bff.car.services.impl;

import com.alibaba.fastjson.JSONObject;
import com.molichuxing.framework.dto.Paged;
import com.molichuxing.framework.exception.BizException;
import com.molichuxing.gateway.bff.car.convertor.Convert;
import com.molichuxing.gateway.bff.car.entity.request.create.AccidentExamineCreateVo;
import com.molichuxing.gateway.bff.car.entity.response.AccidentBizVo;
import com.molichuxing.gateway.bff.car.entity.response.AccidentDetailVo;
import com.molichuxing.gateway.bff.car.entity.response.AccidentVerifyBizVo;
import com.molichuxing.gateway.bff.car.entity.response.CarInsuranceVo;
import com.molichuxing.gateway.bff.car.services.AccidentBffService;
import com.molichuxing.services.business.dto.response.AccidentBizDto;
import com.molichuxing.services.business.dto.response.AccidentDetailDto;
import com.molichuxing.services.business.dto.response.CarInsuranceDto;
import com.molichuxing.services.business.dto.response.UserBizDto;
import com.molichuxing.services.business.service.*;
import com.molichuxing.services.exception.VehicleExceptionCodeEnum;
import com.molichuxing.services.infrastructure.dto.request.create.MessageCenterCreateDto;
import com.molichuxing.services.infrastructure.dto.request.create.NotifyPushCreateDto;
import com.molichuxing.services.infrastructure.dto.response.*;
import com.molichuxing.services.infrastructure.service.*;
import com.molichuxing.services.property.CarAccidentStatusEnum;
import com.molichuxing.services.property.MessageCenterStatusEnum;
import com.molichuxing.services.property.MessageCenterTypeEnum;
import com.molichuxing.services.property.SmsTemplateEnum;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

/**
 * 车辆bff
 * @author xuelin yi
 */
@Service("accidentBffService")
public class AccidentBffServiceImpl implements AccidentBffService {

	private static final Logger logger = LoggerFactory.getLogger(AccidentBffServiceImpl.class);

	@Resource
	private CarAccidentBizService carAccidentBizService;


	@Resource
	private AccidentService accidentService;

	@Resource
	private UserService userService;

	@Resource
	private UserBizService userBizService;

	@Resource
	private InsuranceCompanyService insuranceCompanyService;

	@Resource
	private RegionService regionService;

	@Resource
	private SmsBizService smsBizService;

	@Resource
	private MessageTemplateService messageTemplateService;

	@Resource
	private MessageCenterService messageCenterService;

	@Resource
	private NotifyPushService notifyPushService;

	@Resource
	private CarService carService;

	@Resource
	private VehicleBizService vehicleBizService;

	@Resource
	private VehiclePictureService vehiclePictureService;

	@Override
	public Paged<AccidentBizVo> getCarAccidentPage(Map<String, Object> map, Integer pageNum, Integer pageSize) {
		UserDto userDto = null;
		if(map.get("userName") != null) {
			userDto = userService.getUserByName(map.get("userName").toString());
			if(null == userDto) {
				map.put("userId", -1);
			}else {
				map.put("userId", userDto.getId());
			}
		}
		Paged<AccidentBizDto> page = carAccidentBizService.getCarAccidentPage(map, pageNum, pageSize);
		if(null == page) {
			return null;
		}
		Map<String ,String> vehicleMap = new HashMap<>();
		List<AccidentBizDto> resultList = page.getList();
		if(null != resultList) {
			for(AccidentBizDto accidentBizDto : resultList) {
				if(null != accidentBizDto.getVehicleId()) {
					vehicleMap.put(accidentBizDto.getVehicleId(), vehicleBizService.getVehicleName(Integer.parseInt(accidentBizDto.getVehicleId())));
				}
			}
		}
		Paged<AccidentBizVo> resultVo = Convert.toCarAccidentVoPage(page, getUserMap(page.getList()),vehicleMap);
		if ((null != resultVo) && (null != resultVo.getList())) {
			for (AccidentBizVo accidentBizVo : resultVo.getList()) {
				List<VehiclePictureDto> pictures = vehiclePictureService.getVehiclePictureByVehicleId(accidentBizVo.getVehicleId());
				if (pictures != null && !pictures.isEmpty()) {
					for (VehiclePictureDto picture : pictures) {
						if (picture.getIsWhiteBg() && 1 == picture.getPicDetailType()) {
							accidentBizVo.setVehicleImg(picture.getServerUrl());
							break;
						}
					}
				}
			}
		}
		return resultVo;
	}

	@Override
	public List<AccidentBizVo> getCarAccidentList(Integer carId) {
		List<AccidentBizDto> result = carAccidentBizService.getAccidentByCarId(carId);
		return Convert.toCarAccidentVoPage(result, getUserMap(result), null);
	}

	@Override
	public AccidentDetailVo getAccident(Integer accidentId) throws Exception {
		AccidentDetailDto accidentDetailDto = carAccidentBizService.getAccident(accidentId);
		AccidentDetailVo accidentDetailVo =  Convert.toAccidentDetailVo(accidentDetailDto);
		if(null == accidentDetailVo) {
			return null;
		}
		UserDto userDto = null;
		if(null != accidentDetailDto&& null != accidentDetailDto.getAccidentCarUserDto()) {
			Integer userId = accidentDetailDto.getAccidentCarUserDto().getUserId();
			userDto = userService.getUser(userId);
			if(null != userDto) {
				accidentDetailVo.getAccidentCarUserVo().setUserName(userDto.getRealName());
				accidentDetailVo.getAccidentCarUserVo().setUserPhone(userDto.getPhone());
			}
			Integer commercialCompanyId = accidentDetailDto.getAccidentCarUserDto().getCommercialCompanyId();
			InsuranceCompanyDto insuranceCompanyDto = insuranceCompanyService.getInsuranceCompanyName(commercialCompanyId);
			if(null != insuranceCompanyDto) {
				accidentDetailVo.getAccidentCarUserVo().setCommercialCompany(insuranceCompanyDto.getName());
			}
			Integer compulsoryCompanyId = accidentDetailDto.getAccidentCarUserDto().getCompulsoryCompanyId();
			InsuranceCompanyDto compulsoryCompanyDto = insuranceCompanyService.getInsuranceCompanyName(compulsoryCompanyId);
			if(null != compulsoryCompanyDto) {
				accidentDetailVo.getAccidentCarUserVo().setCompulsoryCompany(compulsoryCompanyDto.getName());
			}
		}
		if(null != accidentDetailDto&& null != accidentDetailDto.getAccidentInfoDto()) {
			RegionInfoDto regionInfoDto = regionService.getCityNameByAreaId(accidentDetailDto.getAccidentInfoDto().getRegionId());
			accidentDetailVo.getAccidentInfoVo().setAccidentAddr(regionInfoDto.getProvinceFullName()+regionInfoDto.getCityFullName()+regionInfoDto.getAreaFullName()+accidentDetailDto.getAccidentInfoDto().getAccidentAddr());
		}
		return accidentDetailVo;
	}

	@Override
	public AccidentVerifyBizVo verifyRepeat(Integer accidentId, Integer version) throws Exception {
		AccidentDto accident = accidentService.getCarAccident(accidentId);
		if(null == accident) {
			throw new BizException("数据不存在");
		}
		AccidentVerifyBizVo accidentVerifyBizVo = new AccidentVerifyBizVo();
		if(version.equals(accident.getVersion())) {
			accidentVerifyBizVo.setResult(false);
			return accidentVerifyBizVo;
		}
		accidentVerifyBizVo.setResult(true);
		UserBizDto userBizDto = userBizService.getUser(accident.getUserId());
		String name = "";
		if(null != userBizDto) {
			name = userBizDto.getRealName();
		}
		accidentVerifyBizVo.setReason("用户"+name+"已重新提交事故报备信息，请刷新页面后，重新审核");
		return accidentVerifyBizVo;
	}

	@Override
	public Boolean modifyExamineAccident(AccidentExamineCreateVo createDto) throws Exception {
		AccidentDto accident = accidentService.getCarAccident(createDto.getAccidentId());
		if(null == accident) {
			throw new BizException("数据不存在");
		}
		UserDto userDto = userService.getUser(accident.getUserId());
		Map<String, MessageTemplateDto> templateMap = messageTemplateService
				.getByKey(Arrays.asList("instation_accident_remind_confirm_push", "instation_accident_remind_confirm_message"
						, "instation_accident_remind_invalid_push", "instation_accident_remind_invalid_message"
						, "instation_case_remind_confirm_push", "instation_case_remind_confirm_message"));
		CarDto carDto = carService.getCarById(accident.getCarId());
		if(null == carDto) {
			throw new BizException("车辆数据不存在");
		}
		Boolean result = carAccidentBizService.modifyExamineAccident(Convert.toAccidentExamineCreateDto(createDto));
		if(!result) {
			return result;
		}
		JSONObject json = new JSONObject();
		json.put("plate",carDto.getLicencePlate());
		if(createDto.getType() == 1) {
			if(createDto.getAccidentStatus() == 1) {
				smsBizService.sendMessage(userDto.getPhone(), SmsTemplateEnum.ACCIDENT_CONFIRM.getValue(), json.toJSONString(), null);
				// 发送推送
				MessageTemplateDto messageTemplateDto = templateMap.get("instation_accident_remind_confirm_push");
				String body = messageTemplateDto.getBody().replace("${licencePlate}", carDto.getLicencePlate());
				try {
					NotifyPushCreateDto notifyPush = new NotifyPushCreateDto(Arrays.asList(userDto.getPhone()),
							messageTemplateDto.getSubject(), messageTemplateDto.getSubject(), body, body, null, "");
					notifyPushService.notifyPushByAlias(notifyPush);
				} catch (Exception e) {
					logger.error("事故(" + createDto.getAccidentId() + ")审核完成发送消息异常：", e);
				}
				// 保存消息
				MessageTemplateDto messageTemplate = templateMap.get("instation_accident_remind_confirm_message");
				String message = messageTemplate.getBody().replace("${licencePlate}", carDto.getLicencePlate());
				MessageCenterCreateDto messageCenterCreateDto = new MessageCenterCreateDto();
				messageCenterCreateDto.setUserId(userDto.getId());
				messageCenterCreateDto.setTitle("报备审核结果通知");
				messageCenterCreateDto.setMessage(message);
				messageCenterCreateDto.setType(MessageCenterTypeEnum.REPORT_CONFIRMATION_RESULTS_NOTICE.getValue());
				messageCenterCreateDto.setStatus(MessageCenterStatusEnum.UNREAD.getValue());
				messageCenterService.createMessageCenter(messageCenterCreateDto);
			}else if(createDto.getAccidentStatus() == 2) {
				smsBizService.sendMessage(userDto.getPhone(), SmsTemplateEnum.ACCIDENT_INVALID.getValue(), json.toJSONString(), null);
				// 发送推送
				MessageTemplateDto messageTemplateDto = templateMap.get("instation_accident_remind_invalid_push");
				String body = messageTemplateDto.getBody().replace("${licencePlate}", carDto.getLicencePlate());
				try {
					NotifyPushCreateDto notifyPush = new NotifyPushCreateDto(Arrays.asList(userDto.getPhone()),
							messageTemplateDto.getSubject(), messageTemplateDto.getSubject(), body, body, null, "");
					notifyPushService.notifyPushByAlias(notifyPush);
				} catch (Exception e) {
					logger.error("事故(" + createDto.getAccidentId() + ")审核完成发送消息异常：", e);
				}
				// 保存消息
				MessageTemplateDto messageTemplate = templateMap.get("instation_accident_remind_invalid_message");
				String message = messageTemplate.getBody().replace("${licencePlate}", carDto.getLicencePlate());
				MessageCenterCreateDto messageCenterCreateDto = new MessageCenterCreateDto();
				messageCenterCreateDto.setUserId(userDto.getId());
				messageCenterCreateDto.setTitle("报备审核结果通知");
				messageCenterCreateDto.setMessage(message);
				messageCenterCreateDto.setType(MessageCenterTypeEnum.REPORT_CONFIRMATION_RESULTS_NOTICE.getValue());
				messageCenterCreateDto.setStatus(MessageCenterStatusEnum.UNREAD.getValue());
				messageCenterService.createMessageCenter(messageCenterCreateDto);
			}
		}else if(createDto.getType() == 2) {
			smsBizService.sendMessage(userDto.getPhone(), SmsTemplateEnum.CASE_CONFIRM.getValue(), json.toJSONString(), null);
			// 发送推送
			MessageTemplateDto messageTemplateDto = templateMap.get("instation_case_remind_confirm_push");
			String body = messageTemplateDto.getBody().replace("${licencePlate}", carDto.getLicencePlate());
			try {
				NotifyPushCreateDto notifyPush = new NotifyPushCreateDto(Arrays.asList(userDto.getPhone()),
						messageTemplateDto.getSubject(), messageTemplateDto.getSubject(), body, body, null, "");
				notifyPushService.notifyPushByAlias(notifyPush);
			} catch (Exception e) {
				logger.error("事故(" + createDto.getAccidentId() + ")审核完成发送消息异常：", e);
			}
			// 保存消息
			MessageTemplateDto messageTemplate = templateMap.get("instation_case_remind_confirm_message");
			String message = messageTemplate.getBody().replace("${licencePlate}", carDto.getLicencePlate());
			MessageCenterCreateDto messageCenterCreateDto = new MessageCenterCreateDto();
			messageCenterCreateDto.setUserId(userDto.getId());
			messageCenterCreateDto.setTitle("结案审核结果通知");
			messageCenterCreateDto.setMessage(message);
			messageCenterCreateDto.setType(MessageCenterTypeEnum.FINAL_CONFIRMATION_RESULTS_NOTICE.getValue());
			messageCenterCreateDto.setStatus(MessageCenterStatusEnum.UNREAD.getValue());
			messageCenterService.createMessageCenter(messageCenterCreateDto);
		}
		return result;
	}

	private Map<Integer, UserBizDto> getUserMap(List<AccidentBizDto> beanList) {
		Map<Integer, UserBizDto> result = new HashMap<>();
		if((null != beanList)&&(beanList.size() > 0)) {
			List<Integer> userIds = new ArrayList<>();
			for(AccidentBizDto bean : beanList) {
				userIds.add(bean.getUserId());
			}
			result = userBizService.getUsers(userIds);
		}
		return result;
	}
}
